/*
 * Copyright 2011-2012 Redia A/S
 * 
 * This file is part of Redias Library App for Android.
 *
 *  Redia Library App for Android is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Redia Library App for Android is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with Redia Library App for Android.  If not, see <http://www.gnu.org/licenses/>.
 */
package dk.redia.libraryapp.net;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import dk.redia.lib.log.Log;
import dk.redia.lib.utils.AppConfiguration;
import dk.redia.lib.xmlrpc.XmlRpcClientCallTask;
import dk.redia.lib.xmlrpc.XmlRpcClientResultListener;
import dk.redia.lib.xmlrpc.XmlRpcResultDumper;
import dk.redia.lib.xmlrpc.XmlRpcResultUtils;
import dk.redia.libraryapp.model.SearchResultDataItem;
import dk.redia.libraryapp.xmlrpc.library.XmlRpcClient;

public class SearchResultsRemoteListManager extends RemoteListManager<SearchResultDataItem> {
	
	private static final String logTag = "SearchResultsRemoteListManager";
	
	public static final String PARAM_KEY_QUERY = "query";
	public static final String PARAM_KEY_CONTENT_CATEGORY = "contentCategory";
	
	public static final String EXTRA_RESULT_DATA_KEY_FACET_MAP = "facetMap";
		
	private XmlRpcClientCallTask currentSearchTask = null;
	private int adjustOffsetForCollections = 0;
	
	@Override
	public void reset() {
		if (currentSearchTask!=null) {
			Log.d(logTag, "Cancelling current search task");
			// If there is already a search in progress, cancel it to avoid
			// building up a backlog of async search tasks
			currentSearchTask.cancel(true);
		}
		adjustOffsetForCollections = 0;
		super.reset();
	}
	
	@Override
	public void loadListChunk(final int offset, final int count) {
		
		String query = (String)getParam(PARAM_KEY_QUERY);
		final String contentCategory = (String)getParam(PARAM_KEY_CONTENT_CATEGORY);
		
		currentSearchTask = XmlRpcClient.getInstance().search(
				AppConfiguration.getInstance().getCustomerId(),
				AppConfiguration.getInstance().getApiKey(), 
				query, 
				count, 
				offset, 
				contentCategory, 
				new XmlRpcClientResultListener() {
			
			public void callFailed(String message) {
				chunkLoadFailed(offset, count, message);
				Log.e(logTag, "XML-RPC call to search() failed: " + message);
			}
			
			
			public void callCompleted(Object result) {
				XmlRpcResultDumper.dump(result);
				try {
					Map<String, Object> r = XmlRpcResultUtils.unpackStandardResult(result);
					Boolean haveData = (Boolean)r.get("result");
					String message = (String)r.get("message");
					if (haveData) {
						Map<String, Object> data = XmlRpcResultUtils.unpackStruct(r.get("data"));

						// Update result count display
						Integer resultCount = (Integer)data.get("hitCount");

						Map<String, Integer> resultFacetMap = new HashMap<String, Integer>();
						Object[] facetTerms = XmlRpcResultUtils.unpackArray(data.get("facetTerm"));
						resultFacetMap.put("", resultCount);
						
						if (facetTerms!=null) {
							for (Object facetObj : facetTerms) {
								Map<String, Object> facetMap = XmlRpcResultUtils.unpackStruct(facetObj);
								String term = (String)facetMap.get("term");
								Integer frequence = (Integer)facetMap.get("frequence");
								Log.d(logTag, "Discovered category: " + term + "(" + frequence + ")");
								resultFacetMap.put(term, frequence);
							}
						}
						
						if (contentCategory.equals("")) {
							setExtraResultData(EXTRA_RESULT_DATA_KEY_FACET_MAP, resultFacetMap);
						}

						List<SearchResultDataItem> srds = new ArrayList<SearchResultDataItem>();
						Object[] results = XmlRpcResultUtils.unpackArray(data.get("results"));
						if (results != null && results.length != 0) {
							for (Object mapObj : results) {
								Map<String, Object> map = XmlRpcResultUtils.unpackStruct(mapObj);
								SearchResultDataItem srdi = SearchResultDataItem.fromMap(map);
								if (srdi.getChildren().size() > 0) {
									adjustOffsetForCollections += srdi.getChildren().size() - 1;
								}
								Log.d(logTag, "Found result: " + srdi);
								srds.add(srdi);
							}
							chunkLoaded(offset, resultCount - adjustOffsetForCollections, srds);
						} else {
							chunkLoadFailed(offset, count, "Serveren returnerede ingen information");
						}						
					} else {
						Log.e(logTag, "Search failed: " + message);
						chunkLoadFailed(offset, count, message);
					}
				} catch (ClassCastException e) {
					e.printStackTrace();
				}
			}
		});
	}
}
